<?php


namespace app\api\controller;
use app\model\A;
use app\model\Aa;
use app\model\DeviceRecords;
use Darabonba\OpenApi\OpenApiClient;

use AlibabaCloud\SDK\Iot\V20180120\Iot;
use \Exception;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;

use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Iot\V20180120\Models\QueryDeviceDetailRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
use AlibabaCloud\Tea\Console\Console;
use AlibabaCloud\SDK\Iot\V20180120\Models\RRpcRequest;
use \PhpMqtt\Client\MqttClient;
use \PhpMqtt\Client\ConnectionSettings;

use Stomp\Client;
use Stomp\Exception\StompException;
use Stomp\Network\Observer\Exception\HeartbeatException;
use Stomp\Network\Observer\ServerAliveObserver;
use Stomp\StatefulStomp;
use AlibabaCloud\SDK\Iot\V20180120\Models\PubRequest;
use app\model\Device;
class Aliyuniot
{


    /**
     * 使用AK&SK初始化账号Client
     * @param string $accessKeyId
     * @param string $accessKeySecret
     * @return Iot Client
     */
    public static function createClient($accessKeyId="LTAI5t8fu2Bed5aT5R9pqyku", $accessKeySecret="rxwE7p8OSlp8k0c94FxEek0VEG7WqY"){
        $config = new Config([
            // 必填，您的 AccessKey ID
            "accessKeyId" => $accessKeyId,
            // 必填，您的 AccessKey Secret
            "accessKeySecret" => $accessKeySecret
        ]);
        // 访问的域名
        $config->endpoint = "iot.cn-shanghai.aliyuncs.com";
        return new Iot($config);
    }

    /**
     * 使用STS鉴权方式初始化账号Client，推荐此方式。本示例默认使用AK&SK方式。
     * @param string $accessKeyId
     * @param string $accessKeySecret
     * @param string $securityToken
     * @return Iot Client
     */
    public static function createClientWithSTS($accessKeyId, $accessKeySecret, $securityToken)
    {
        $config = new Config([
            // 必填，您的 AccessKey ID
            "accessKeyId" => $accessKeyId,
            // 必填，您的 AccessKey Secret
            "accessKeySecret" => $accessKeySecret,
            // 必填，您的 Security Token
            "securityToken" => $securityToken,
            // 必填，表明使用 STS 方式
            "type" => "sts"
        ]);
        // 访问的域名
        $config->endpoint = "iot.cn-shanghai.aliyuncs.com";
        return new Iot($config);
    }

    /**
     * @param string[] $args
     * @return void
     */
    public static function device_detail($device_no)
    {
        // 工程代码泄露可能会导致AccessKey泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/311677.html

        try {
            $client = self::createClient();
            $queryDeviceDetailRequest = new QueryDeviceDetailRequest([
                "iotInstanceId" => "iot-06z00eflfgjdvpq",
                "productKey" => "hy91biYirJS",
                "deviceName" => $device_no
            ]);
            $runtime = new RuntimeOptions([]);
            $resp = $client->queryDeviceDetailWithOptions($queryDeviceDetailRequest, $runtime);
            return ($resp->body->data);
            Console::log(Utils::toJSONString($resp));
        } catch (\Exception $e) {
            return ('错误');
        }



    }

    public static function send_msg()
    {
        // 工程代码泄露可能会导致AccessKey泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/311677.html
        $client = self::createClient();
        $RRpcRequest = new RRpcRequest([
            "productKey" => "i3br4zraEIP",
            "deviceName" => "diaolanbang",
            "iotInstanceId" => "iot-06z00elmt6qvwvn",
            "requestBase64Byte" => "ZXJlcmVy",
            "timeout" => 1000
        ]);
        $runtime = new RuntimeOptions([]);
        $resp = $client->rRpcWithOptions($RRpcRequest, $runtime);
        return $resp;

    }

    public function mqtt()
    {

        $server = 'iot-06z00elmt6qvwvn.mqtt.iothub.aliyuncs.com';
        $port = 1883;
        $clientId = 'i3br4zraEIP.diaolanbang|securemode=2,signmethod=hmacsha256,timestamp=1675925076502|';
        $username = 'diaolanbang&i3br4zraEIP';
        $password = 'e6c4250fd66a9355b10970e86d18a48cbd7a6aab34ae5eb8ab27d595781a44d2';
        $clean_session = false;

        $connectionSettings = new ConnectionSettings();
        $connectionSettings
            ->setUsername($username)
            ->setPassword($password)
            ->setKeepAliveInterval(60)
            // Last Will 设置
            ->setLastWillTopic('i3br4zraEIP/diaolanbang/user/push')
            ->setLastWillMessage('client disconnect')
            ->setLastWillQualityOfService(1);

        $mqtt = new MqttClient($server, $port, $clientId);

        $mqtt->connect($connectionSettings, $clean_session);
die;
        $mqtt->subscribe('/i3br4zraEIP/diaolanbang/user/get', function ($topic, $message) {
            printf("Received message on topic [%s]: %s\n", $topic, $message);
        }, 0);

        for ($i = 0; $i < 10; $i++) {
            $payload = array(
                'protocol' => 'tcp',
                'date' => date('Y-m-d H:i:s'),
                'url' => 'https://github.com/emqx/MQTT-Client-Examples'
            );
            $mqtt->publish(
            // topic
                '/i3br4zraEIP/diaolanbang/user/get',
                // payload
                json_encode($payload),
                // qos
                0,
                // retain
                true
            );
            printf("msg $i send\n");
            sleep(1);
        }

        $mqtt->loop(true);
    }

    public function amqp(){

//参数说明，请参见AMQP客户端接入说明文档。
        $accessKey = "LTAI5t8fu2Bed5aT5R9pqyku";
        $accessSecret = "KaU45X7a3moZcjIxq0C9UMt7pgRY0V";
        $consumerGroupId = "DEFAULT_GROUP";
        $clientId = rand(1,100);
//iotInstanceId：实例ID。
        $iotInstanceId = "iot-06z00eflfgjdvpq";
        $timeStamp = round(microtime(true) * 1000);
//签名方法：支持hmacmd5，hmacsha1和hmacsha256。
        $signMethod = "hmacsha1";
//userName组装方法，请参见AMQP客户端接入说明文档。
//若使用二进制传输，则userName需要添加encode=base64参数，服务端会将消息体base64编码后再推送。具体添加方法请参见下一章节“二进制消息体说明”。
        $userName = $clientId . "|authMode=aksign"
            . ",signMethod=" . $signMethod
            . ",timestamp=" . $timeStamp
            . ",authId=" . $accessKey
            . ",iotInstanceId=" . $iotInstanceId
            . ",consumerGroupId=" . $consumerGroupId
            . "|";
        $signContent = "authId=" . $accessKey . "&timestamp=" . $timeStamp;
//计算签名，password组装方法，请参见AMQP客户端接入说明文档。
        $password = base64_encode(hash_hmac("sha1", $signContent, $accessSecret, $raw_output = TRUE));
//接入域名，请参见AMQP客户端接入说明文档。
        $client = new Client('ssl://iot-06z00elmt6qvwvn.amqp.iothub.aliyuncs.com:61614');

        $sslContext = ['ssl' => ['verify_peer' => true, 'verify_peer_name' => false], ];
        $client->getConnection()->setContext($sslContext);

        //服务端心跳监听。
        $observer = new ServerAliveObserver();
        $client->getConnection()->getObservers()->addObserver($observer);
        //心跳设置，需要云端每30s发送一次心跳包。
        $client->setHeartbeat(0, 1000);
        $client->setLogin($userName, $password);

        try {
            $client->connect();

        }
        catch(StompException $e) {
            echo "failed to connect to server, msg:" . $e->getMessage() , PHP_EOL;
        }

//无异常时继续执行。
        $stomp = new StatefulStomp($client);
        $stomp->subscribe('/topic/#');
        $data = $stomp->read();
//        dump($body->getBody());
//        dump($body->getCommand());
//        dump($body->body);
//        dump($body->legacyMode());
//        dump($body);
//        dump($body->getHeaders());


//        $data['device_name'] = explode('/',$data['topic'])[2];
//        $data['content'] = $stomp->read()->getBody();
//        $data['message_id'] = $data['message-id'];
        $ret= $stomp->read();
        dump($ret);
//        DeviceRecords::create([
//            "qos" => $ret['qos'],
//            "destination" => $ret['destination'],
//            "message_id" => $ret['message-id'],
//            "topic" => $ret['topic'],
//            "subscription" => $ret['subscription'],
//            "generateTime" => $ret['generateTime'],
//            "device_name" => explode('/',$ret['topic'])[2],
//            "content" => $stomp->read()->getBody()
//        ]);

        die;
//        $getCommand = $stomp->read()->getHeaders();
//        halt($getCommand);
////            writeLog('amqp');
//        return $getCommand;die;
//       return $stomp->read();die;
        while (true) {
            try {

                // 检查连接状态
                if (!$client->isConnected()) {
                    echo "connection not exists, will reconnect after 10s.", PHP_EOL;
//                    sleep(1);
                    $client->connect();
                    $stomp->subscribe('/topic/#');
                    echo "connect success", PHP_EOL;
                }

                //处理消息业务逻辑。
//                dump($stomp->read()->getHeaders());
//                dump($stomp->read()->getBody());
               echo $stomp->read();
//                writeLog($stomp->read());
            }
            catch(HeartbeatException $e) {
                echo 'The server failed to send us heartbeats within the defined interval.', PHP_EOL;
                $stomp->getClient()->disconnect();
            } catch(Exception $e) {
                echo 'process message occurs error: '. $e->getMessage() , PHP_EOL;
                $stomp->getClient()->disconnect();
            }
        }
    }


    public static function pub($cmd = 'ok',$device_name,$id=0){
        // 工程代码泄露可能会导致AccessKey泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/311677.html
        $client = self::createClient();

        $pubRequest = new PubRequest([
            "topicFullName" => "/hy91biYirJS/{$device_name}/user/get",
            "productKey" => "hy91biYirJS",
            "iotInstanceId" => "iot-06z00eflfgjdvpq",
            "messageContent" => base64_encode($cmd)
        ]);
        $runtime = new RuntimeOptions([]);
        $resp = $client->pubWithOptions($pubRequest, $runtime);
        $msg = 'OK';
        if($cmd == 'Openn'){
            $msg = '开机指令';
            Device::where('id',$id)->update(['remote_status'=>'开机']);
        }
        if($cmd == 'Close'){
            $msg = '关机指令';
            //Device::where('id',$id)->update(['remote_status'=>'关机']);
        }
        if($cmd == 'Pause'){
            $msg = '暂停指令';
           // Device::where('id',$id)->update(['remote_status'=>'暂停']);
        }
        if($cmd == 'BalON'){
            $msg = '平衡(开)';
           // Device::where('id',$id)->update(['balance'=>'平衡(开)']);
        }
        if($cmd == 'BaOFF'){
            $msg = '平衡(关)';
            //Device::where('id',$id)->update(['balance'=>'平衡(关)']);
        }
        if($cmd == 'OvlON'){
            $msg = '超载(开)';
           // Device::where('id',$id)->update(['overload'=>'超载(关)']);
        }
        if($cmd == 'OvOFF'){
            $msg = '超载(关)';
           // Device::where('id',$id)->update(['overload'=>'超载(关)']);
        }


        return json(['code'=>200,'msg'=>$msg.'已发送','ret'=>$resp]);
    }

    public function msg(){
        writeLog('msg');
    }
    public function cmd(){
        \think\facade\Console::call('am');
    }

    public function a(){
       for ($i=113878;$i<=300000;$i++){
          $ret =  (new A())->insert(['part_number'=>$i,'num'=>1]);


       }
    }
    public function aa(){
        for ($i=0;$i<=30000;$i++){
            $ret =  (new Aa())->insert(['part_number'=>$i,'num'=>1]);


        }
    }

    public function look(){
        DeviceRecords::create([
            "qos" => "1",
            "destination" => "/i3br4zraEIP/diaolanbang/user/push",
            "message_id" => "1633365805192502786",
            "topic" => "/i3br4zraEIP/diaolanbang/user/push",
            "subscription" => "6574851102897074786",
            "generateTime" => "1678259729084",
            "device_name" => "diaolanbang",
            "content" => "gotoschool"
        ]);
        $s = '/i3br4zraEIP/diaolanbang/user/pus';
        dump(explode('/',$s)[2]);
        die;
        set_time_limit(0);
        $ret =  (new A())->with('Aa')->select();

        return $ret;

    }

    public function w(){
        while (true){
            echo time();
            sleep(1);

        }
    }


    public function craete_time()
    {
        $user = \app\model\Member::find();

            if ($user_count == 1 && $user['create_time'] < time() && $user['14time'] < time()) {

            }else{
                //'花钱的次数'
            }


    }



}

